package com.aboo.infrastructure.aop.frame.aop;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ClassName PointAspect
 * @Description
 * @Author louan
 * @Date 2021/3/23
 */
@Slf4j
@Aspect
@Order(value = 2)
@Component
public class PointAspect {

    private final String POINT_CUT = "execution(public * com.aboo.*.service..*.*(..))";

    @Pointcut(POINT_CUT)
    public void pointCut() {
    }

    /**
     * 前置通知, 在方法执行之前执行
     **/
    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint) {
        log.info("开始PointAspect的before");
        log.info("============================================================");
        //获取目标方法参数信息
        Object[] objects = joinPoint.getArgs();
        log.info("Args:{}", JSONArray.toJSONString(objects));

        //aop代理对象
        Object thisObject = joinPoint.getThis();
        log.info("thisObject:{}", JSONObject.toJSONString(thisObject));

        //被代理对象
        Object proxyObject = joinPoint.getTarget();
        log.info("proxyObject:{}", JSON.toJSONString(proxyObject));

        //获取连接点的方法签名对象
        Signature signature = joinPoint.getSignature();
        log.info("signature:{}", signature.toString());

        //获取方法名
        String methodName = signature.getName();
        log.info("method:{}", methodName);
        log.info("============================================================");
    }

    /**
     * 后置通知, 在方法执行之后执行
     **/
    @After(value = "pointCut()")
    public void after(JoinPoint joinPoint) {
        log.info("开始PointAspect的after");
    }

    /**
     * 返回通知, 在方法返回结果之后执行
     **/
    @AfterReturning(value = "pointCut()")
    public void afterReturning(JoinPoint joinPoint) {
        log.info("开始PointAspect的afterReturning");
    }

    /**
     * 异常通知, 在方法抛出异常之后
     **/
    @AfterThrowing(value = "pointCut()", throwing = "throwable")
    public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {
        log.info("开始PointAspect的afterThrowing");
    }

    /**
     * 环绕通知, 围绕着方法执行
     **/
    @Around(value = "pointCut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("开始PointAspect的around");
        Object result = proceedingJoinPoint.proceed();
        log.info("结束PointAspect的around");
        return result;
    }

}
